﻿

#include "zyMenu.h"

BOOL DarkMoonUI::zyMenu::创建菜单栏() {//CreateMenu 创建一个菜单栏
	if (m_hMenu != 0)
		return false;
	m_hMenu = CreateMenu();
	return m_hMenu != 0;
}
BOOL DarkMoonUI::zyMenu::创建弹出菜单() {//CreatePopupMenu
	if (m_hMenu != 0)
		return false;
	m_hMenu = CreatePopupMenu();
	return m_hMenu != 0;
}
BOOL DarkMoonUI::zyMenu::绑定系统菜单(HWND  参数_窗口句柄) {//GetSystemMenu
	if (m_hMenu != 0)
		return false;
	m_hMenu = GetSystemMenu(参数_窗口句柄, 0);
	return m_hMenu != 0;
}
void DarkMoonUI::zyMenu::重置系统菜单(HWND  参数_窗口句柄) {
	GetSystemMenu(参数_窗口句柄, 1);
}
void DarkMoonUI::zyMenu::销毁() {//DestroyMenu，清除所占内存。
	MENUINFO 局部_结构;
	if (m_hMenu != 0) {
		局部_结构.cbSize = sizeof(局部_结构);
		局部_结构.fMask = MIM_BACKGROUND;
		GetMenuInfo(m_hMenu, &局部_结构);
		if (局部_结构.hbrBack != 0)
			DeleteObject(局部_结构.hbrBack);
		_DeleteBitmaps(m_hMenu);
		DestroyMenu(m_hMenu);
		m_hMenu = 0;
	}
}
void DarkMoonUI::zyMenu::_DeleteBitmaps(HMENU  hMenu) {
	MENUITEMINFO mii;
	int count = GetMenuItemCount(hMenu);
	if (count == -1)
		return;
	for (int i = 0; i < count; i++) {
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_BITMAP | MIIM_CHECKMARKS;
		GetMenuItemInfo(m_hMenu, i, true, &mii);
		if (mii.hbmpItem != 0)
			DeleteObject(mii.hbmpItem);
		if (mii.hbmpChecked != 0)
			DeleteObject(mii.hbmpChecked);
		if (mii.hbmpUnchecked != 0)
			DeleteObject(mii.hbmpUnchecked);
	}
}
HMENU DarkMoonUI::zyMenu::取菜单句柄() {//获取菜单句柄。
	return m_hMenu;
}
BOOL DarkMoonUI::zyMenu::置菜单句柄(HMENU  参数_菜单句柄) {//将菜单句柄和本类相关联
	if (m_hMenu != 0)
		return false;
	m_hMenu = 参数_菜单句柄;
	return m_hMenu != 0;
}
BOOL DarkMoonUI::zyMenu::添加弹出菜单(zyMenu& 参数_菜单条, const wchar_t* 参数_菜单名) {//AppendPopupMenu
	return AppendMenu(m_hMenu, MF_POPUP | MF_BYPOSITION, (UINT_PTR)参数_菜单条.取菜单句柄(), 参数_菜单名) != 0;
}

BOOL DarkMoonUI::zyMenu::插入弹出菜单(zyMenu& 参数_菜单条, const wchar_t* 参数_菜单名, int  参数_索引) {//InsertPopupMenu
	if (参数_索引 == -1)
		参数_索引 = GetMenuItemCount(m_hMenu);
	return InsertMenu(m_hMenu, 参数_索引, MF_POPUP | MF_BYPOSITION, (UINT_PTR)参数_菜单条.取菜单句柄(), 参数_菜单名) != 0;
}
BOOL DarkMoonUI::zyMenu::置窗口(HWND  参数_窗口句柄) {//SetMenu
	int 局部_return值 = SetMenu(参数_窗口句柄, m_hMenu);
	DrawMenuBar(参数_窗口句柄);
	return 局部_return值 != 0;
}
BOOL DarkMoonUI::zyMenu::置菜单背景色(int  参数_颜色值, BOOL  参数_应用于所有子菜单) {//成功returntrue，失败returnfalse。
	MENUINFO 局部_结构;
	局部_结构.cbSize = sizeof(局部_结构);
	局部_结构.fMask = MIM_BACKGROUND | (参数_应用于所有子菜单 ? MIM_APPLYTOSUBMENUS : 0);
	GetMenuInfo(m_hMenu, &局部_结构);
	if (局部_结构.hbrBack != 0)
		DeleteObject(局部_结构.hbrBack);
	局部_结构.hbrBack = CreateSolidBrush(参数_颜色值);
	int 局部_return值 = SetMenuInfo(m_hMenu, &局部_结构);
	return 局部_return值 != 0;
}
BOOL DarkMoonUI::zyMenu::置菜单背景图(Bitmap 参数_图片, int 参数_图片背景色, BOOL 参数_应用于所有子菜单) {//成功returntrue，失败returnfalse。
	MENUINFO 局部_结构;
	HBITMAP hBitmap;
	局部_结构.cbSize = sizeof(局部_结构);
	局部_结构.fMask = MIM_BACKGROUND | (参数_应用于所有子菜单 ? MIM_APPLYTOSUBMENUS : 0);
	GetMenuInfo(m_hMenu, &局部_结构);
	if (局部_结构.hbrBack != 0)
		DeleteObject(局部_结构.hbrBack);
	if (参数_图片背景色 == 0)
		参数_图片背景色 = GetSysColor(COLOR_BTNFACE);
	参数_图片.GetHBITMAP(参数_图片背景色, &hBitmap);
	局部_结构.hbrBack = CreatePatternBrush(hBitmap);
	int 局部_return值 = SetMenuInfo(m_hMenu, &局部_结构);
	DeleteObject(hBitmap);
	return 局部_return值 != 0;
}
DarkMoonUI::zyMenu DarkMoonUI::zyMenu::取子菜单(int  参数_索引) {//return一个弹出式菜单
	zyMenu 局部_菜单;
	局部_菜单.置菜单句柄(GetSubMenu(m_hMenu, 参数_索引));
	return 局部_菜单;
}
int DarkMoonUI::zyMenu::取项目ID(int  参数_索引) {		//return位于菜单中指定位置处的项目ID。如项目属于一个弹出式菜单，就return-1；如指定的项目属于一个分隔线则return0
	return GetMenuItemID(m_hMenu, 参数_索引);
}
BOOL DarkMoonUI::zyMenu::添加项目(const wchar_t* 参数_菜单名, int  参数_菜单ID) {//添加菜单项目。
	return AppendMenu(m_hMenu, MF_STRING, 参数_菜单ID, 参数_菜单名) != 0;
}
BOOL DarkMoonUI::zyMenu::添加分割线() {
	return AppendMenu(m_hMenu, MF_SEPARATOR, 0, 0) != 0;
}
BOOL DarkMoonUI::zyMenu::插入项目(wchar_t* 参数_菜单名, int  参数_索引, int  参数_菜单ID) {//在指定位置处插入一个菜单项目。成功returntrue，失败returnfalse。
	return InsertMenu(m_hMenu, 参数_索引, MF_BYPOSITION | MF_STRING, 参数_菜单ID, 参数_菜单名) != 0;
}
BOOL DarkMoonUI::zyMenu::插入分割线(int  参数_索引) {//在指定位置处插入一个菜单项目。成功returntrue，失败returnfalse。
	return InsertMenu(m_hMenu, 参数_索引, MF_BYPOSITION | MF_SEPARATOR, 0, 0) != 0;
}
BOOL DarkMoonUI::zyMenu::单选菜单(int  参数_索引, int  参数_分组起始索引, int  参数_分组结束索引) {//成功returntrue，失败returnfalse。
	return CheckMenuRadioItem(m_hMenu, 参数_分组起始索引, 参数_分组结束索引, 参数_索引, MF_BYPOSITION) != 0;
}
int DarkMoonUI::zyMenu::弹出菜单(int  参数_X, int  参数_Y, HWND  参数_窗口句柄, int  参数_标志) {//在屏幕的任意位置弹出菜单。if设置了"菜单弹出_return菜单ID"，则return菜单ID
	SetForegroundWindow(参数_窗口句柄);
	return TrackPopupMenu(m_hMenu, 参数_标志, 参数_X, 参数_Y, 0, 参数_窗口句柄, 0);
}
const wchar_t* DarkMoonUI::zyMenu::取项目标题(int 菜单ID, BOOL 使用索引) {
	// 初始尝试使用较小的缓冲区来获取菜单项标题的长度  
	wchar_t 局部_缓冲区[256];
	int 长度 = GetMenuString(m_hMenu, 菜单ID, 局部_缓冲区, sizeof(局部_缓冲区) / sizeof(wchar_t),
		使用索引 ? MF_BYPOSITION : MF_BYCOMMAND);

	// 如果缓冲区太小，则重新分配足够大的缓冲区  
	if (长度 == sizeof(局部_缓冲区) / sizeof(wchar_t) - 1) { // 减去1以考虑可能的空终止符  
		// 分配足够的空间（包括空终止符）  
		wchar_t* 局部_缓冲区1 = new wchar_t[长度 + 1];
		if (GetMenuString(m_hMenu, 菜单ID, 局部_缓冲区1, 长度 + 1,
			使用索引 ? MF_BYPOSITION : MF_BYCOMMAND) == 0) {
			// 如果获取失败，则释放内存并返回nullptr  
			delete[] 局部_缓冲区1;
			return nullptr;
		}
		return 局部_缓冲区1; // 成功时返回分配的内存  
	}
	else if (长度 > 0) {
		// 如果初始缓冲区足够大，则直接使用它（但需要复制以避免返回局部变量的地址）  
		wchar_t* 局部_缓冲区_copy = new wchar_t[长度 + 1];
		wcsncpy_s(局部_缓冲区_copy, 长度 + 1, 局部_缓冲区, 长度);
		局部_缓冲区_copy[长度] = L'\0'; // 确保字符串是正确终止的  
		return 局部_缓冲区_copy;
	}

	// 如果长度为0或小于0（理论上不应该发生，但为了完整性检查），则返回nullptr  
	return nullptr;
}
int DarkMoonUI::zyMenu::取项目风格(int  参数_菜单ID或索引, BOOL  参数_使用索引) {//return"菜单项目风格_"常量组合
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_FTYPE;
	GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构);
	return 局部_项目结构.fType;
}
RECT DarkMoonUI::zyMenu::取项目矩形(HWND  参数_窗口句柄, int  参数_菜单索引) {//取得指定菜单在屏幕的坐标位置信息，成功returntrue，失败returnfalse。
	RECT 局部_矩形;
	GetMenuItemRect(参数_窗口句柄, m_hMenu, 参数_菜单索引, &局部_矩形);
	return 局部_矩形;
}
INT_PTR DarkMoonUI::zyMenu::取项目数值(int  参数_菜单ID或索引, BOOL  参数_使用索引) {//return菜单数值
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_DATA;
	GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构);
	return 局部_项目结构.dwItemData;
}
int DarkMoonUI::zyMenu::取项目数() {//取得指定菜单句柄的项目总数。
	return GetMenuItemCount(m_hMenu);
}
int DarkMoonUI::zyMenu::取项目状态(int  参数_菜单ID, BOOL  参数_使用索引) {//成功return菜单所有状态的组合，见"菜单状态_"常量。
	return GetMenuState(m_hMenu, 参数_菜单ID, (参数_使用索引 ? MF_BYPOSITION : MF_BYCOMMAND));
}
int DarkMoonUI::zyMenu::取默认项目(int 参数_标志, BOOL 参数_使用索引) {//return菜单ID或索引。
	return GetMenuDefaultItem(m_hMenu, 参数_使用索引, 参数_标志);
}
int DarkMoonUI::zyMenu::取坐标项目(HWND 参数_窗口句柄, int 参数_横坐标, int  参数_纵坐标) {//成功return菜单索引，失败return-1。
	POINT 局部_POINT;
	局部_POINT.x = 参数_横坐标;
	局部_POINT.y = 参数_纵坐标;
	return MenuItemFromPoint(参数_窗口句柄, m_hMenu, 局部_POINT);
}
BOOL DarkMoonUI::zyMenu::取项目图标(int 参数_菜单ID或索引, Bitmap 参数_位图, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_BITMAP;
	if (GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) == 0)
		return false;
	参数_位图.FromHBITMAP(局部_项目结构.hbmpItem, NULL);
	return true;
}
BOOL DarkMoonUI::zyMenu::取项目图标选中(int 参数_菜单ID或索引, Bitmap 参数_未选中位图, Bitmap 参数_已选中位图, BOOL 参数_使用索引) {//获取项目被选中时使用的位图
	MENUITEMINFO itemInfo;
	itemInfo.cbSize = sizeof(itemInfo);
	itemInfo.fMask = MIIM_CHECKMARKS;
	if (GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &itemInfo) == 0)
		return false;
	if (itemInfo.hbmpChecked != 0)
		参数_已选中位图.FromHBITMAP(itemInfo.hbmpChecked, NULL);
	if (itemInfo.hbmpUnchecked != 0)
		参数_未选中位图.FromHBITMAP(itemInfo.hbmpUnchecked, NULL);
	return true;
}
BOOL DarkMoonUI::zyMenu::删除项目(int 参数_菜单ID或索引, BOOL 参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO mii = { 0 };;
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_BITMAP | MIIM_CHECKMARKS;
	GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &mii);
	if (mii.hbmpItem != 0)
		DeleteObject(mii.hbmpItem);
	if (mii.hbmpChecked != 0)
		DeleteObject(mii.hbmpChecked);
	if (mii.hbmpUnchecked != 0)
		DeleteObject(mii.hbmpUnchecked);
	return RemoveMenu(m_hMenu, 参数_菜单ID或索引, 参数_使用索引 ? MF_BYPOSITION : MF_BYCOMMAND) != 0;
}
int DarkMoonUI::zyMenu::选中项目(int  参数_菜单ID或索引, BOOL  参数_是否选中, BOOL  参数_使用索引) {//if之前状态为选中，就return常量_菜单状态_选中，否则return菜单状态_取消选中。失败return-1。
	return CheckMenuItem(m_hMenu, 参数_菜单ID或索引, (参数_是否选中 ? MF_CHECKED : MF_UNCHECKED) | (参数_使用索引 ? MF_BYPOSITION : MF_BYCOMMAND));
}
BOOL DarkMoonUI::zyMenu::是否选中(int  参数_菜单ID或索引, BOOL  参数_使用索引) {
	return  (GetMenuState(m_hMenu, 参数_菜单ID或索引, (参数_使用索引 ? MF_BYPOSITION : MF_BYCOMMAND)) & 8) != 0;
}
BOOL DarkMoonUI::zyMenu::置项目ID(int  参数_菜单ID或索引, int  参数_新菜单ID, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_ID;
	局部_项目结构.wID = 参数_新菜单ID;
	return SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) != 0;
}
BOOL DarkMoonUI::zyMenu::置项目标题(int  参数_菜单ID或索引, const wchar_t* 参数_菜单标题, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_STRING;
	局部_项目结构.dwTypeData = (LPWSTR)参数_菜单标题;
	return SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) != 0;
}
BOOL DarkMoonUI::zyMenu::置项目风格(int  参数_菜单ID或索引, int  参数_风格, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_FTYPE;
	局部_项目结构.fType = 参数_风格;
	return SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) != 0;
}
BOOL DarkMoonUI::zyMenu::载入RC资源(int 参数_菜单栏资源ID)
{
	if (m_hMenu != 0)
		return false;
	m_hMenu = LoadMenu(zyEnv::getInstance().getHandle(), MAKEINTRESOURCE(参数_菜单栏资源ID));
	return m_hMenu != 0;
}
BOOL DarkMoonUI::zyMenu::置项目数值(int  参数_菜单ID或索引, int  参数_菜单数值, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_DATA;
	局部_项目结构.dwItemData = 参数_菜单数值;
	return SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) != 0;
}
BOOL DarkMoonUI::zyMenu::置项目图标(int  参数_菜单ID或索引, Bitmap 参数_图标, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_BITMAP;
	GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构);
	if (局部_项目结构.hbmpItem != 0)
		DeleteObject(局部_项目结构.hbmpItem);
	参数_图标.GetHBITMAP(GetSysColor(COLOR_BTNFACE), &局部_项目结构.hbmpItem);
	int ret = SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构);
	return ret != 0;
}
BOOL DarkMoonUI::zyMenu::置项目图标选中(int  参数_菜单ID或索引, Bitmap 参数_未选中图标, Bitmap 参数_已选中图标, BOOL  参数_使用索引) {//设置一幅特定图标，令其在指定的菜单项目中使用，代替标准的选中符号（√）。
	MENUITEMINFO itemInfo;
	itemInfo.cbSize = sizeof(itemInfo);
	itemInfo.fMask = MIIM_CHECKMARKS;
	GetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &itemInfo);
	if (itemInfo.hbmpChecked != 0)
		DeleteObject(itemInfo.hbmpChecked);
	if (itemInfo.hbmpUnchecked != 0)
		DeleteObject(itemInfo.hbmpUnchecked);
	参数_已选中图标.GetHBITMAP(GetSysColor(COLOR_BTNFACE), &itemInfo.hbmpChecked);
	参数_未选中图标.GetHBITMAP(GetSysColor(COLOR_BTNFACE), &itemInfo.hbmpUnchecked);
	int ret = SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &itemInfo);
	return ret != 0;
}
BOOL DarkMoonUI::zyMenu::置项目状态(int  参数_菜单ID或索引, int  参数_菜单状态, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。
	MENUITEMINFO 局部_项目结构;
	局部_项目结构.cbSize = sizeof(局部_项目结构);
	局部_项目结构.fMask = MIIM_STATE;
	局部_项目结构.fState = 参数_菜单状态;
	return SetMenuItemInfo(m_hMenu, 参数_菜单ID或索引, 参数_使用索引, &局部_项目结构) != 0;
}
BOOL DarkMoonUI::zyMenu::置默认项目(int  参数_菜单ID或索引, BOOL  参数_使用索引) {//成功returntrue，失败returnfalse。当在一个弹出式菜单上双击鼠标，就会自动选择默认的菜单项目。
	return SetMenuDefaultItem(m_hMenu, 参数_菜单ID或索引, (参数_使用索引 ? MF_BYPOSITION : MF_BYCOMMAND)) != 0;
}
